/**
 * \file
 *
 * \brief Empty user application template
 *
 */

/**
 * \mainpage User Application template doxygen documentation
 *
 * \par Empty user application template
 *
 * This is a bare minimum user application template.
 *
 * For documentation of the board, go \ref group_common_boards "here" for a link
 * to the board-specific documentation.
 *
 * \par Content
 *
 * -# Include the ASF header files (through asf.h)
 * -# Minimal main function that starts with a call to board_init()
 * -# Basic usage of on-board LED and button
 * -# "Insert application code here" comment
 *
 */

/*
 * Include header files for all drivers that have been imported from
 * Atmel Software Framework (ASF).
 */
#include <sam.h>

#define SPI_INSTANCE SPI
#define SPI_CLOCK_PRES 30
#define CS_PIN_PORT PIOA
#define CS_PIN_NUM  13
#define DUMMY_WRITE_DATUM 0xFF


void spi_init(void);
void spi_read_write(uint8_t * Txbuff , uint8_t * Rxbuff , uint64_t xfersize );
void spi_write(uint8_t * Txbuff, uint64_t xfersize );
void spi_read(uint8_t * Rxbuff , uint64_t xfersize );


void spi_init(void)
{
	
	//Enable GPIOA Clock
	PMC->PMC_PCER0 = PMC_PCER0_PID11;
	//Configure 
	PIOA->PIO_PDR = (PIO_PER_P11 | PIO_PER_P12 | PIO_PER_P13 | PIO_PER_P14);
	PIOA->PIO_ABCDSR[0] &= ~(PIO_PER_P11 | PIO_PER_P12 | PIO_PER_P13 | PIO_PER_P14);
	PIOA->PIO_ABCDSR[1] &= ~(PIO_PER_P11 | PIO_PER_P12 | PIO_PER_P13 | PIO_PER_P14);
	
	// Enable SPI Clock
	PMC->PMC_PCER0 |= PMC_PCER0_PID21 ;

	// Enable SPI
	SPI_INSTANCE->SPI_CR |= SPI_CR_SPIEN;
	// Reset SPI
    SPI_INSTANCE->SPI_MR |= SPI_MR_WDRBT;

	// Configure SPI Mode : CPOL=0 CPHA=0
	SPI_INSTANCE->SPI_CSR[0] &= ~(SPI_CSR_CPOL);
	SPI_INSTANCE->SPI_CSR[0] |= SPI_CSR_NCPHA;

	// Set frequency (optional)  
	SPI_INSTANCE->SPI_CSR[0] |= SPI_CLOCK_PRES << (SPI_CSR_SCBR_Pos);	 	

	// Enable SPI interrupt at NVIC level
	NVIC_EnableIRQ(SPI_IRQn);
	
	// Enable SPI peripheral interrupts 
	SPI->SPI_IER |= (SPI_IER_OVRES | SPI_IER_UNDES | SPI_IER_TXBUFE | SPI_IER_RXBUFF );
}

void SPI_Handler(void)
{
	uint32_t Status;
	Status = SPI->SPI_SR;
	
	// Data received (Receive buffer full) 
	if (Status & SPI_SR_RDRF)
	{
		SPI->SPI_RDR;
	}	
	
	// Prepare data to transmit (Transmit buffer Empty)
	if (Status & SPI_SR_TXBUFE)
	{
		SPI->SPI_TDR = 0xA5;
	}
	
}

int main (void)
{ 
	SystemInit();
	// Initialize SPI 
	spi_init();	
	while(1);

}
